
#include "ffconf.h"
#include "stm32_eval_sdio_sd.h"
#include "stm32_sd.h"
#include "stm32f10x.h"
#include "log.h"
#include "diskio.h"
#include <string.h>

#define SECTOR_SIZE 512U


/**
 * @brief  Initializes the SD Card(disk) 
 * @param  drv: [in] Physical drive nmuber (0..)
 * @retval STA_NOINIT: SD Card Error code.
 */
DSTATUS disk_initialize (BYTE drv )
{
    SD_Error state;
#if _MULTI_PARTITION == 0  
    if ( drv ){
		DEBUG_OUT("DISKIO(%s,line:%d)drv num error \n",__FUNCTION__, __LINE__);
        return STA_NOINIT;  
    }
#endif

#if 1
    state = STM32_SD_Init();
	
    if ( state != SD_OK ) {
		DEBUG_OUT("DISKIO(%s,line:%d)sd Init error \n",__FUNCTION__, __LINE__);
        return STA_NOINIT;  
    }
#endif
    return 0;          

}

/**
 * @brief  Initializes the SD Card(disk) 
 * @param drv: [in] Physical drive nmuber (0..)
 * @retval STA_NODISK: no SD Card(disk).
 */
DSTATUS disk_status (	BYTE drv )
{
#if _MULTI_PARTITION == 0  
	if ( drv ){
		DEBUG_OUT("DISKIO(%s,line:%d)drv num error \n",__FUNCTION__, __LINE__);
		return STA_NOINIT;	
	}
#endif

#if 0
    if ( SD_GetState() == SD_CARD_ERROR ){
		DEBUG_OUT("DISKIO(%s,line:%d)get sd state error \n",__FUNCTION__, __LINE__);
		return STA_NODISK;
    }
#endif
	
	return 0;
}

/**
 * @brief  Initializes the SD Card(disk) 
 * @param drv: [in]    Physical drive nmuber (0..)
 *             buff: [out] Data buffer to store read data 
 *             sector [in] Sector address (LBA)
 *             count [in]  Number of sectors to read (1..255)
 * @retval RES_PARERR: SD Card(disk) not ready or error.
 */

DRESULT disk_read (BYTE drv, BYTE *buff, DWORD sector, BYTE count)
{
	SD_Error err = SD_OK;
#if _MULTI_PARTITION == 0  
	if ( drv ){
		DEBUG_OUT("DISKIO(%s,line:%d)drv num error \n",__FUNCTION__, __LINE__);
		return RES_PARERR;	
	}
#endif

	switch(count)
	{
		case 0:
			err = SD_ERROR;
		break;
		case 1:
			err = SD_ReadBlock(buff,sector<<9,SECTOR_SIZE);
		break;
		default:
			err = SD_ReadMultiBlocks(buff,sector<<9,SECTOR_SIZE,count);
		break;
	}

	if (err == SD_OK)
	{
		return RES_OK;
	}
	
	DEBUG_OUT("read error at (%d)\n",sector);

	return RES_ERROR;
	
}


#if _READONLY == 0
/**
 * @brief  Initializes the SD Card(disk) 
 * @param drv:    [in]   Physical drive nmuber (0..)
 *             buff:   [out] Data buffer to be written 
 *             sector [in]   Sector address (LBA)
 *             count  [in]   Number of sectors to read (1..255)
 * @retval RES_PARERR: SD Card(disk) not ready or error.
 */
DRESULT disk_write (BYTE drv, const BYTE *buff, DWORD sector, 	BYTE count)
{
	SD_Error err = SD_OK;
#if _MULTI_PARTITION == 0  
	if ( drv ){
		DEBUG_OUT("DISKIO(%s,line:%d)drv num error \n",__FUNCTION__, __LINE__);
		return RES_PARERR;	
	}
#endif

	switch(count)
	{
		case 0:
			err = SD_ERROR;
		break;
		case 1:
			err = SD_WriteBlock((u8*)buff,sector<<9,SECTOR_SIZE);
		break;
		default:
			err = SD_WriteMultiBlocks((u8*)buff,sector<<9,SECTOR_SIZE,count);
		break;
	}

	if (err == SD_OK)
	{
		return RES_OK;
	}
	DEBUG_OUT("write error at (%d)\n",sector);

	return RES_ERROR;


}

#endif

/**
 * @brief  Initializes the SD Card(disk) 
 * @param drv: [in]    Physical drive nmuber (0..)
 *             ctrl  [in]    Control code
 *             buff [in]    Buffer to send/receive control data
 * @retval RES_PARERR: SD Card(disk) not ready or error.
 */
DRESULT disk_ioctl (BYTE drv, BYTE ctrl, void *buff)
{
    DRESULT res = RES_OK;
	SD_CardInfo cardinfo;


#if _MULTI_PARTITION == 0 
		if ( drv ){
			DEBUG_OUT("DISKIO(%s,line:%d)drv num error \n",__FUNCTION__, __LINE__);
			return RES_PARERR;	
		}
#endif

    
    //FATFS now version just need proccess CTRL_SYNC,GET_SECTOR_COUNT,GET_BLOCK_SIZ and so on command
    switch(ctrl)
    {
    case CTRL_SYNC:
		//while (SD_GetStatus() == SD_TRANSFER_OK);

        break;        
    case GET_BLOCK_SIZE:
        *(WORD*)buff = SECTOR_SIZE;
        res = RES_OK;
		
        break;

    case GET_SECTOR_COUNT:
		if ( SD_GetCardInfo(&cardinfo) == SD_OK ){ 
        	*(DWORD*)buff = cardinfo.CardCapacity;
		}
		else{
			DEBUG_OUT("DISKIO(%s,line:%d)get \n",__FUNCTION__, __LINE__);
			res = RES_ERROR;
		}
        break;
    default:
        res = RES_PARERR;
        break;
    }

    return res;
}


/*-----------------------------------------------------------------------*/
/* User defined function to give a current time to fatfs module          */
/* 31-25: Year(0-127 org.1980), 24-21: Month(1-12), 20-16: Day(1-31) */                                                                                                                                                                                                                                          
/* 15-11: Hour(0-23), 10-5: Minute(0-59), 4-0: Second(0-29 *2) */                                                                                                                                                                                                                                                
DWORD get_fattime (void)
{
   
    return 0;
}


